<template>
  <div class="markdown-viewer-layout">
    <aside class="markdown-toc">
      <div class="toc-title">目录</div>
      <ul>
        <li v-for="item in toc" :key="item.id" :class="'toc-h' + item.level">
          <a :href="'#' + item.id" @click.prevent="scrollTo(item.id)">{{ item.text }}</a>
        </li>
      </ul>
    </aside>
    <main class="markdown-content" v-html="renderedHtml"></main>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'

const route = useRoute()
const renderedHtml = ref('')
const toc = ref([])

const md = new MarkdownIt({
  html: true,
  highlight: (str, lang) => {
    const copySvg = `<svg class='copy-svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='9' width='13' height='13' rx='2' ry='2'></rect><path d='M5 15V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v2'></path></svg>`
    const checkSvg = `<svg class='check-svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='#3B82F6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>`
    if (lang && hljs.getLanguage(lang)) {
      return `<pre class='hljs code-block dark-block'><code>${hljs.highlight(str, { language: lang }).value}</code><button class='copy-btn' title='复制代码' data-state="copy">${copySvg}${checkSvg}</button></pre>`
    }
    return `<pre class='hljs code-block dark-block'><code>${md.utils.escapeHtml(str)}</code><button class='copy-btn' title='复制代码' data-state="copy">${copySvg}${checkSvg}</button></pre>`
  }
})

function genToc(html) {
  const temp = document.createElement('div')
  temp.innerHTML = html
  const headings = temp.querySelectorAll('h1, h2, h3, h4, h5, h6')
  const tocArr = []
  headings.forEach(h => {
    if (!h.id) h.id = 'toc-' + Math.random().toString(36).slice(2, 10)
    tocArr.push({
      id: h.id,
      text: h.textContent,
      level: Number(h.tagName[1])
    })
  })
  return tocArr
}

async function loadMarkdown() {
  const filename = route.params.filename
  const files = import.meta.glob('/public/docs/*.md', { query: '?raw', import: 'default' })
  // 兼容Vite glob返回的key格式，确保和filename匹配
  const key = Object.keys(files).find(k => {
    const kFile = decodeURIComponent(k.split('/').pop())
    const fFile = decodeURIComponent(filename)
    // 调试输出
    // eslint-disable-next-line no-console
    console.log('匹配key:', kFile, '参数:', fFile)
    return kFile === fFile
  })
  if (key) {
    const raw = await files[key]()
    // 给标题加id，便于锚点跳转
    let html = md.render(raw)
    html = html.replace(/<h([1-6])>([\s\S]*?)<\/h\1>/g, (m, level, text) => {
      const id = 'h' + level + '-' + text.replace(/<[^>]+>/g, '').replace(/\s+/g, '-').replace(/[^\w\-]/g, '')
      return `<h${level} id="${id}">${text}</h${level}>`
    })
    renderedHtml.value = html
    toc.value = genToc(html)
  } else {
    renderedHtml.value = '<p>未找到该文档</p>'
    toc.value = []
  }
}

function scrollTo(id) {
  const el = document.getElementById(id)
  if (el) {
    el.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

function handleCopy(e) {
  if (e.target.classList.contains('copy-btn') || e.target.closest('.copy-btn')) {
    const btn = e.target.classList.contains('copy-btn') ? e.target : e.target.closest('.copy-btn')
    const code = btn.previousElementSibling
    if (code) {
      navigator.clipboard.writeText(code.textContent)
      btn.setAttribute('data-state', 'success')
      setTimeout(() => {
        btn.setAttribute('data-state', 'copy')
      }, 1000)
    }
  }
}

onMounted(() => {
  loadMarkdown()
  document.querySelector('.markdown-content')?.addEventListener('click', handleCopy)
})
watch(() => route.params.filename, loadMarkdown)
</script>

<style scoped>
.markdown-viewer-layout {
  display: flex;
  min-height: 100vh;
  background: #f7f8fa;
}
.markdown-toc {
  width: 220px;
  background: #fff;
  border-right: 1px solid #eee;
  padding: 24px 12px 24px 24px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.toc-title {
  font-weight: bold;
  font-size: 1.2rem;
  margin-bottom: 16px;
}
.markdown-toc ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.markdown-toc li {
  margin-bottom: 8px;
}
.toc-h1 { margin-left: 0; font-weight: bold; }
.toc-h2 { margin-left: 12px; }
.toc-h3 { margin-left: 24px; }
.toc-h4 { margin-left: 36px; }
.toc-h5 { margin-left: 48px; }
.toc-h6 { margin-left: 60px; }
.markdown-content {
  flex: 1;
  padding: 40px 32px;
  background: #f7f8fa;
  min-width: 0;
  overflow-x: auto;
  text-align: left;
  max-width: 900px;
  margin: 0;
}
.code-block {
  position: relative;
  background: #222 !important;
  border-radius: 6px;
  margin-bottom: 1.5em;
  padding-top: 12px;
  color: #f8f8f2;
}
.dark-block code {
  background: transparent !important;
  color: #f8f8f2;
  font-family: 'Fira Mono', 'Consolas', 'Menlo', monospace;
  font-size: 1em;
}
.copy-btn {
  position: absolute;
  top: 8px;
  right: 12px;
  background: transparent;
  color: #fff;
  border: none;
  border-radius: 4px;
  font-size: 1em;
  padding: 2px 6px;
  cursor: pointer;
  opacity: 0.85;
  transition: background 0.2s;
  z-index: 2;
  display: flex;
  align-items: center;
}
.copy-btn:hover {
  background: #444;
  opacity: 1;
}
.copy-btn .copy-svg {
  display: inline;
}
.copy-btn .check-svg {
  display: none;
}
.copy-btn[data-state="success"] .copy-svg {
  display: none;
}
.copy-btn[data-state="success"] .check-svg {
  display: inline;
}
</style> 